package values.city
{
import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher;

import utils.VectorUtil;

import values.common.SimplePlayerValue;
import values.events.CityValueEvent;
import values.events.LevelEvent;
import values.item.BuildingItemValue;
import values.item.ResourceItemValue;
import values.level.CityLevelValue;

[Event(name="readyToLevelUp", type="values.events.CityValueEvent")]
[Event(name="addBuilding", type="values.events.CityValueEvent")]
[Event(name="removeBuilding", type="values.events.CityValueEvent")]
/**
 * CityValue
 * @author jliang
 *
 */
public class CityValue extends EventDispatcher
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function CityValue()
	{
		super();
	}
	//==========================================================================
	//  Properties
	//==========================================================================
	protected var _owner:SimplePlayerValue;

	public function get owner():SimplePlayerValue
	{
		return _owner;
	}
	
	protected var _levelValue:CityLevelValue;

	public function get levelValue():CityLevelValue
	{
		return _levelValue;
	}
	
	public function get level():int
	{
		return levelValue.level;
	}
	
	public function get population():Number
	{
		return levelValue.resource;
	}
	
	protected var buildings:Vector.<BuildingItemValue>;
	
	public function get buildingCount():int
	{
		return buildings.length;
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	/**
	 * 初始化 
	 * @param owner
	 * @param level
	 * @param population
	 * @param buildings
	 * 
	 */	
	public function initialize(owner:SimplePlayerValue, level:int, population:ResourceItemValue, buildings:Vector.<BuildingItemValue>):void
	{
		this._owner = owner;
		
		_levelValue = new CityLevelValue();
		levelValue.init(level, population);
		
		this.buildings = buildings;
		
		levelValue.addEventListener(LevelEvent.READY_TO_LEVEL_UP, readyToLevelUpHandler);
	}
	
	/**
	 * 垃圾回收 
	 * 
	 */	
	public function dispose():void
	{
		if (levelValue)
		{
			levelValue.removeEventListener(LevelEvent.READY_TO_LEVEL_UP, readyToLevelUpHandler);
			levelValue.dispose();
			_levelValue = null;
		}
	}
	
	/**
	 * 根据UID获取指定建筑 
	 * @param uid
	 * @return 
	 * 
	 */	
	public function getBuildingByUID(uid:String):BuildingItemValue
	{
		for each (var building:BuildingItemValue in buildings)
		{
			if (building.uid == uid) return building;
		}
		return null;
	}
	
	/**
	 *  根据自定义的过滤方法, 选择满足条件的建筑
	 * @param filterFunc
	 * @param args
	 * @return 
	 * 
	 */	
	public function getBuildingsByCustomFilter(filterFunc:Function, ...args):Vector.<BuildingItemValue>
	{
		var list:Vector.<BuildingItemValue> = new Vector.<BuildingItemValue>();
		
		for each (var building:BuildingItemValue in buildings)
		{
			if (filterFunc.apply(this, [ building ].concat(args))) list.push(building);
		}
		
		return list;
	}
	
	/**
	 * 获取某类型的所有建筑 
	 * @param type
	 * @return 
	 * 
	 */	
	public function getBuildingsByType(type:String):Vector.<BuildingItemValue>
	{
		var func:Function = function(building:BuildingItemValue, targetType:String):Boolean
		{
			if (building.template.type == targetType) return true;			
			return false;
		};
		
		var list:Vector.<BuildingItemValue> = getBuildingsByCustomFilter(func, type);		
		return list;
	}
	
	/**
	 * 获取某类型的所有建筑 
	 * @param ref
	 * @return 
	 * 
	 */	
	public function getBuildingsByClassRef(ref:Class):Vector.<BuildingItemValue>
	{
		var func:Function = function(building:BuildingItemValue, targetRef:Class):Boolean
		{
			if (building is targetRef) return true;			
			return false;
		};
		
		var list:Vector.<BuildingItemValue> = getBuildingsByCustomFilter(func, ref);		
		return list;
	}
	
	/**
	 *  获取某类型的所有建筑 
	 * @param key
	 * @return 
	 * 
	 */	
	public function getBuildingsByTemplateKey(key:String):Vector.<BuildingItemValue>
	{
		var func:Function = function(building:BuildingItemValue, targetKey:String):Boolean
		{
			if (building.key == targetKey) return true;			
			return false;
		};
		
		var list:Vector.<BuildingItemValue> = getBuildingsByCustomFilter(func, key);		
		return list;
	}
	
	/**
	 * 添加新建筑 
	 * @param building
	 * 
	 */	
	public function addBuilding(building:BuildingItemValue):void
	{
		if (buildings.indexOf(building) != -1) throw new IllegalOperationError("The building <" + building.uid + "> has already exsited. Cannot add again.");
		
		buildings.push(building);
		
		var evt:CityValueEvent = new CityValueEvent(CityValueEvent.ADD_BUILDING);
		evt.params = { city:this, building: building };
		this.dispatchEvent(evt);
	}
	
	/**
	 * 移除建筑 
	 * @param building
	 * 
	 */	
	public function removeBuilding(building:BuildingItemValue):void
	{
		if (buildings.indexOf(building) == -1) return;
		
		VectorUtil.removeObject(building, buildings);
		
		var evt:CityValueEvent = new CityValueEvent(CityValueEvent.REMOVE_BUILDING);
		evt.params = { city:this, building: building };
		this.dispatchEvent(evt);
	}
	//==========================================================================
	//  Event handlers
	//==========================================================================
	protected function readyToLevelUpHandler(event:LevelEvent):void
	{
		var evt:CityValueEvent = new CityValueEvent(CityValueEvent.READY_TO_LEVEL_UP);
		evt.params = { city:this };
		this.dispatchEvent(evt);
	}
}
}




